package com.sinovate.liteEMS.session.dao;

import java.io.Serializable;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.ValidatingSession;
import org.apache.shiro.session.mgt.eis.CachingSessionDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;

import com.sinovate.liteEMS.dao.RedisClientTemplate;
import com.sinovate.liteEMS.utils.SerializableUtils;

public class MySqlSessionDAO extends CachingSessionDAO {

	@Autowired
	private JdbcTemplate jdbcTemplate;
	@Resource(name = "redisClientTemplate")
	private RedisClientTemplate redisTemplate;

	@Override
	protected Serializable doCreate(Session session) {
		Serializable sessionId = generateSessionId(session);
		assignSessionId(session, sessionId);
		redisTemplate.set(sessionId.toString(),
				SerializableUtils.serialize(session));
		String sql = "insert into sessions(id, session) values(?,?)";
		jdbcTemplate.update(sql, sessionId,
				SerializableUtils.serialize(session));
		return session.getId();
	}

	@Override
	protected void doUpdate(Session session) {
		if (session instanceof ValidatingSession
				&& !((ValidatingSession) session).isValid()) {
			return; // 如果会话过期/停止 没必要再更新了
		}
		redisTemplate.set(session.getId().toString(),
				SerializableUtils.serialize(session));
		String sql = "update sessions set session=? where id=?";
		jdbcTemplate.update(sql, SerializableUtils.serialize(session),
				session.getId());
	}

	@Override
	public void doDelete(Session session) {
		redisTemplate.del(session.getId().toString());
		String sql = "delete from sessions where id=?";
		jdbcTemplate.update(sql, session.getId());
	}

	@Override
	protected Session doReadSession(Serializable sessionId) {
		if (redisTemplate.exists(sessionId.toString())) {
			String ss = redisTemplate.get(sessionId.toString());
			return SerializableUtils.deserialize(ss.toString());
		} else {
			String sql = "select session from sessions where id=?";
			List<String> sessionStrList = jdbcTemplate.queryForList(sql,
					String.class, sessionId);
			if (sessionStrList.size() == 0) {
				return null;
			} else {
				redisTemplate.set(sessionId.toString(), sessionStrList.get(0)
						.toString());
				redisTemplate.expire(sessionId.toString(), 1800);
				return SerializableUtils.deserialize(sessionStrList.get(0));
			}
		}
	}

	@Override
	public Collection<Session> getActiveSessions(){
		HashSet<Session> sessionSet = new HashSet<Session>();
		Map<String, Object> allEntrys = redisTemplate.getAllEntrys();
		for (Map.Entry<String, Object> entry : allEntrys.entrySet()) {
			Object value = entry.getValue();
			if (value instanceof String) {
				sessionSet.add(SerializableUtils.deserialize(value.toString()));
			}
		}
		return sessionSet;
	}
	
	@Override
	public void uncache(Session session){
		super.uncache(session);
	}
	
	@Override
	public void update(Session session){
		super.update(session);
	}
	
}